﻿using Cemit.PolyProto;
using Google.Protobuf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Cemit.PolyServer
{
    public static class AsyncGetHandles
    {
        static Dictionary<string, IAsyncGetHandle> messagesHandlesPairs;

        static AsyncGetHandles()
        {
            IEnumerable<Type> types = AppDomain.CurrentDomain.SelectTypeImplementsGenericInterface(typeof(IAsyncGetHandle<>));

            messagesHandlesPairs = new Dictionary<string, IAsyncGetHandle>();
            foreach (var type in types)
            {
                foreach (var item in type.GetInterfaces().Where(t => t.IsGenericInterface(typeof(IAsyncGetHandle<>))))
                {
                    messagesHandlesPairs.Add(
                        item.GetGenericArguments()[0].FullName, CreateMessageHandleInstance(type));
                    //Console.WriteLine($"add:{item.GetGenericArguments()[0].Name} {type.Name}");
                }
            }

            IAsyncGetHandle CreateMessageHandleInstance(Type messageHandleType)
                => (IAsyncGetHandle)messageHandleType.Assembly
                    .CreateInstance(messageHandleType.FullName);
        }

        public static IAsyncGetHandle GetHandle(string type)
        {
            if (!messagesHandlesPairs.ContainsKey(type))
            {
                return new NullHandle();
            }
            return messagesHandlesPairs[type];
        }

        public static IAsyncGetHandle GetHandle(this G message)
        {
            return GetHandle(message.Type);
        }

        public static bool IsNull(this IAsyncGetHandle message)
        {
            return message.GetType() == typeof(Nullable);
        }
    }
}
